#ifndef SOURCE_RANGE_HPP
#define SOURCE_RANGE_HPP

#include <utility>

class SourceLocation {
public:
  SourceLocation() : _line(0), _column(0) {}
  SourceLocation(int line, int column) : _line(line), _column(column) {}
  bool invalid() const { return _line <= 0 || _column <= 0; }

  void moveToNext(const char &current) {
    if (current == '\n' || current == '\r') {
      _line++;
      _column = 1;
    } else {
      _column++;
    }
  }

  int _line;
  int _column;
};

class SourceRange {
public:
  SourceRange() : _range({SourceLocation(), SourceLocation()}) {}

  SourceRange(SourceLocation begin, SourceLocation end)
      : _range({begin, end}) {}

  SourceRange(int beginLine, int beginColumn, int endLine, int endColumn)
      : _range({SourceLocation(beginLine, beginColumn),
                SourceLocation(endLine, endColumn)}) {}

  std::pair<SourceLocation, SourceLocation> range() const { return _range; }

  SourceLocation begin() const { return _range.first; }

  SourceLocation end() const { return _range.second; }

  bool invalid() { return _range.first.invalid() || _range.second.invalid(); }

private:
  std::pair<SourceLocation, SourceLocation> _range;
};

#endif
